package com.michael.ims.admin.controller;

import com.michael.config.TokenFilter;
import com.michael.ims.admin.controller.io.system.*;
import com.michael.ims.app.QTblSystem;
import com.michael.ims.app.QTblUser;
import com.michael.ims.app.QTblUserToSystem;
import com.michael.io.*;
import com.michael.plugins.PageHelper;
import com.querydsl.core.types.Projections;
import com.querydsl.sql.SQLQuery;
import com.querydsl.sql.SQLQueryFactory;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.time.LocalDate;
import java.util.List;

@Api(tags = "系统管理")
@RestController
@RequestMapping("/system")
public class SystemController {
    @Autowired
    private SQLQueryFactory sqlQueryFactory;


    @ApiOperation("添加系统")
    @PostMapping("/add")
    @Transactional
    public RespStatus add(@RequestBody @Valid AddSystemReq req) {
        UserInfo userInfo = TokenFilter.TokenHolder.get();
        QTblSystem tblSystem = QTblSystem.tblSystem;
        sqlQueryFactory.insert(tblSystem)
                .set(tblSystem.name, req.getName())
                .set(tblSystem.context, req.getContext())
                .set(tblSystem.url, req.getUrl())
                .set(tblSystem.desc, req.getDesc())
                .set(tblSystem.picture, req.getPicture())
                .set(tblSystem.createOper, userInfo.getName())
                .set(tblSystem.createDate, LocalDate.now())
                .set(tblSystem.modifyOper, userInfo.getName())
                .set(tblSystem.modifyDate, LocalDate.now())
                .executeWithKey(Integer.class);

        return new RespStatus();
    }

    @ApiOperation("修改系统")
    @PostMapping("/edit")
    @Transactional
    public RespStatus edit(@RequestBody @Valid EditSystemReq req) {
        UserInfo userInfo = TokenFilter.TokenHolder.get();
        QTblSystem tblSystem = QTblSystem.tblSystem;
        sqlQueryFactory.update(tblSystem)
                .set(tblSystem.name, req.getName())
                .set(tblSystem.context, req.getContext())
                .set(tblSystem.url, req.getUrl())
                .set(tblSystem.desc, req.getDesc())
                .set(tblSystem.picture, req.getPicture())
                .set(tblSystem.modifyOper, userInfo.getName())
                .set(tblSystem.modifyDate, LocalDate.now())
                .where(tblSystem.id.eq(req.getId()))
                .execute();
        return new RespStatus();
    }

    @ApiOperation("删除系统")
    @PostMapping("/delete")
    @Transactional
    public RespStatus delete(@RequestBody @Valid DeleteSystemReq req) {
        UserInfo userInfo = TokenFilter.TokenHolder.get();
        QTblSystem tblSystem = QTblSystem.tblSystem;
        sqlQueryFactory.update(tblSystem)
                .set(tblSystem.isDelete, true)
                .set(tblSystem.modifyOper, userInfo.getName())
                .set(tblSystem.modifyDate, LocalDate.now())
                .where(tblSystem.id.eq(req.getId()))
                .execute();
        return new RespStatus();
    }

    @ApiOperation("维护系统管理员")
    @PostMapping("/maintain")
    @Transactional
    public RespStatus maintain(@RequestBody @Valid MaintainSystemReq req) {
        QTblUserToSystem tblUserToSystem = QTblUserToSystem.tblUserToSystem;
        //todo 校验
        //删除现有的管理员
        sqlQueryFactory.delete(tblUserToSystem)
                .where(tblUserToSystem.systemId.eq(req.getSystemId())
                        .and(tblUserToSystem.isManager.eq(true)))
                .execute();
        //查询该用户是否拥有访问该系统的权限
        Long id = sqlQueryFactory.select(tblUserToSystem.id)
                .from(tblUserToSystem)
                .where(tblUserToSystem.systemId.eq(req.getSystemId())
                        .and(tblUserToSystem.userId.eq(req.getUserId())))
                .fetchOne();

        if (id != null) {//存在
            sqlQueryFactory.update(tblUserToSystem)
                    .set(tblUserToSystem.isManager, true)
                    .where(tblUserToSystem.id.eq(id))
                    .execute();
        } else {
            sqlQueryFactory.insert(tblUserToSystem)
                    .set(tblUserToSystem.systemId, req.getSystemId())
                    .set(tblUserToSystem.userId, req.getUserId())
                    .set(tblUserToSystem.isManager, true)
                    .execute();
        }
        return new RespStatus();
    }

    @ApiOperation("系统管理列表")
    @PostMapping("/query")
    @Transactional
    public RespData<RespPageBody<QuerySystemVO>> query(@RequestBody @Valid ReqPage<QuerySystemCond> req) {
        QuerySystemCond cond = req.getCondition();
        QTblSystem tblSystem = QTblSystem.tblSystem;
        QTblUser tblUser = QTblUser.tblUser;
        QTblUserToSystem tblUserToSystem = QTblUserToSystem.tblUserToSystem;
        SQLQuery<QuerySystemVO> sqlQuery = sqlQueryFactory.select(Projections.bean(QuerySystemVO.class, tblSystem.id, tblSystem.name, tblUser.name.as("manager"),
                tblSystem.context, tblSystem.url, tblSystem.desc, tblSystem.picture,
                tblSystem.createDate, tblSystem.createOper, tblSystem.modifyDate, tblSystem.modifyOper))
                .from(tblSystem).leftJoin(tblUserToSystem)
                .on(tblSystem.id.eq(tblUserToSystem.systemId).and(tblUserToSystem.isManager.isTrue()))
                .leftJoin(tblUser).on(tblUserToSystem.userId.eq(tblUser.id))
                .where(tblSystem.isDelete.isFalse());

        if (StringUtils.isNotBlank(cond.getName())) {
            sqlQuery.where(tblSystem.name.contains(cond.getName()));
        }

        PageHelper.Page<QuerySystemVO> page = PageHelper.buildPage(req.getPage());
        PageHelper.execute(sqlQuery);

        RespPageBody<QuerySystemVO> body = new RespPageBody();
        body.setPage(page.getPage());
        body.setData(page.getData());

        RespData<RespPageBody<QuerySystemVO>> resp = new RespData();
        resp.setBody(body);
        return resp;
    }


    @ApiOperation("系统列表")
    @GetMapping("/list")
    @Transactional
    public RespData<List<ListSystemResp>> list() {
        QTblSystem tblSystem = QTblSystem.tblSystem;
        List<ListSystemResp> data = sqlQueryFactory.select(Projections.bean(ListSystemResp.class, tblSystem.id, tblSystem.name))
                .from(tblSystem)
                .where(tblSystem.isDelete.isFalse())
                .fetch();
        return new RespData<>(data);
    }
}
